﻿using System;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using System.Reflection;

namespace Assets.Scripts.Globe.DateReader
{
    //key的类型
    public enum KeyType
    {
        Int,
        String,
    }
    /// <summary>
    /// 数据读取的基类
    /// </summary>
    /// <typeparam name="T"></typeparam>
    public abstract class TxtReaderBase<T> : MonoBehaviour where T : ModelBase
    {
        private TextAsset infoText;

        #region 字典

        public Dictionary<int, ModelBase> InfoDictInt { get; set; }
        public Dictionary<string, ModelBase> InfoDictString { get; set; }    

        #endregion

        public static TxtReaderBase<T> _Instance;   

        protected int num;

        protected string[] strArray;

        protected virtual void Awake()
        {
           Init();
        }

        protected virtual void OnDestroy()
        {
            _Instance = null;
        }

        protected void Init()
        {
            _Instance = this;
            switch (KeyType)
            {
                case KeyType.Int:
                    InfoDictInt = new Dictionary<int, ModelBase>();
                    break;
                case KeyType.String:
                    InfoDictString=new Dictionary<string, ModelBase>();
                    break;
            }
            infoText = Resources.Load<TextAsset>(TextPath);
            if(infoText==null)return;
            string text = infoText.text;
            strArray = text.Split('\n');
            num = strArray.Length;
            StartCoroutine(ReadInfos(InitModles(num), strArray));
        }

        public virtual ModelBase GetInfoById(int id)
        {
            ModelBase info = null;
            InfoDictInt.TryGetValue(id, out info);
            return info;         
        }

        /// <summary>
        /// 初始化模型的数量,由于T不能new
        /// </summary>
        /// <returns></returns>
        protected abstract T[] InitModles(int num);        
        //字典中Key的类型
        protected abstract KeyType KeyType { get; }
        protected abstract string TextPath { get; }

        /// <summary>
        /// 读取数据
        /// </summary>
        /// <param name="models"></param>
        /// <param name="strArray"></param>
        /// <returns></returns>
        protected virtual IEnumerator ReadInfos(T[] models,string[] strArray)
        {
            Type t = typeof (T);
            PropertyInfo[] propertyInfos = t.GetProperties();
            int id = 0;
            foreach (var str in strArray)
            {
                id++;
                var proArray = str.Split(',');
                if (proArray.Length != propertyInfos.Length)
                {
                    continue;
                }
                for (int i = 0; i < propertyInfos.Length; i++)
                {
                    switch (propertyInfos[i].PropertyType.ToString())
                    {
                        case "System.Int32":
                            propertyInfos[i].SetValue(models[id - 1], Convert.ToInt32(proArray[i]), null); 
                            break;
                        case "System.Byte":
                            propertyInfos[i].SetValue(models[id - 1], Convert.ToByte(proArray[i]), null); 
                            break;
                        case "System.Boolean":
                            propertyInfos[i].SetValue(models[id - 1], Convert.ToBoolean(proArray[i]), null);
                            break;
                        case "System.Single":
                            propertyInfos[i].SetValue(models[id - 1], Convert.ToSingle(proArray[i]), null);
                            break;
                        case "System.Double":
                            propertyInfos[i].SetValue(models[id - 1], Convert.ToDouble(proArray[i]), null);
                            break;
                        case "System.String":
                            propertyInfos[i].SetValue(models[id - 1], proArray[i], null);
                            break;
                        default:
                            Debug.LogWarning(string.Format("{0}，找不到对应的类型：+请在【{1}】中添加类型【{2}】",t,this,propertyInfos[i].PropertyType));
                            break;
                    }                 
                }
                switch (KeyType)
                {
                    case KeyType.Int: 
                        if (!InfoDictInt.ContainsKey(id))
                        {
                            InfoDictInt.Add(id, models[id - 1]);
                        }
                        break;
                    case KeyType.String:
                        if (!InfoDictString.ContainsKey(proArray[0]))
                        {
                            InfoDictString.Add(proArray[0],models[id-1]);
                        }
                        break;
                }     
            }
            if(InfoDictInt!=null)Debug.Log(InfoDictInt.Count);
            if(InfoDictString!=null)Debug.Log(InfoDictString.Count);
            yield return 0;
        }
    }

    public abstract class ModelBase
    {
        
    }
}